package com.hyf.gateway.filter;

import com.hyf.gateway.constants.CommonConstants;
import com.hyf.gateway.util.EncodeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 接口调用验签
 *
 * @author baB_hyf
 * @date 2021/07/14
 */
@Component
public class CheckSignatureFilter implements GlobalFilter {

    public static final Logger log = LoggerFactory.getLogger(CheckSignatureFilter.class);

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        String contentType = getHeaderFirstValue(headers, "Content-Type", "");
        if (!contentType.contains("application/json")) { //  && !contentType.contains("application/x-www-form-urlencoded")
            return chain.filter(exchange);
        }

        // TODO 验证cookie校验是否通过，或者上面过滤掉 form 类型的请求

        String paasId = getHeaderFirstValue(headers, "x-tif-paasid", "");
        String timestamp = getHeaderFirstValue(headers, "x-tif-timestamp", "");
        String nonce = getHeaderFirstValue(headers, "x-tif-nonce", "");
        String signature = getHeaderFirstValue(headers, "x-tif-signature", "");

        // token get from paasId
        String paasToken = CommonConstants.TOKEN;

        String s = EncodeUtils.sha256(timestamp + paasToken + nonce + timestamp);
        boolean checkSuccess = s.equalsIgnoreCase(signature);


        if (!checkSuccess) {

            log.warn("验签失败：{}\n{}", request.getURI().toString(), headers);

            ServerHttpResponse response = exchange.getResponse();
            response.setStatusCode(HttpStatus.UNAUTHORIZED);

            return Mono.empty();
        }

        return chain.filter(exchange);
    }

    private String getHeaderFirstValue(HttpHeaders headers, String headerName, String defaultValue) {
        List<String> headerValueList = headers.get(headerName);
        if (headerValueList == null) {
            return defaultValue;
        }

        return headerValueList.get(0);
    }
}
